<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 重写ES6数组方法(forEach filter map some every reduce) 主要涉及call或apply的用法 可以用来重新定义函数的执行环境 (this指向)

    // let arr = [1, 2, 3, 4, 1, 2]

    // 1. 重写forEach
    // Array.prototype.myForEach = function (func) {
    //   var item = this
    //   var len = item.length
    //   var arg = arguments[1] || window

    //   for (var i = 0; i < len; i++) {
    //     func.apply(arg, [item[i], i, item])
    //   }
    // }

    // Array.prototype.myForEach = function (cb) {
    //   for (var i = 0; i < this.length; i++) {
    //     cb(this[i], i, this)
    //   }
    // }

    // arr.myForEach((item, ind, arr) => {
    //   console.log(item, ind, arr);
    // })



    // 2.重写filter

    // var arr = [
    //   {
    //     name: "张三",
    //     age: 34,
    //   },
    //   {
    //     name: "李四",
    //     age: 25,
    //   },
    //   {
    //     name: "王五",
    //     age: 21,
    //   },
    //   {
    //     name: "刘六",
    //     age: 28,
    //   },
    // ];
    // var obj = {
    //   name: "Jacky",
    //   age: 3,
    // };


    // function deepClone (obj) {
    //   let newObj = obj.push ? [] : {}; //如果obj有push方法则 定义newObj为数组，否则为对象。
    //   for (let attr in obj) {
    //     if (typeof obj[attr] === "object") {
    //       newObj[attr] = deepClone(obj[attr]);
    //     } else {
    //       newObj[attr] = obj[attr];
    //     }
    //   }
    //   return newObj;
    // }

    // Array.prototype.myFilter = function (func) {
    //   var _arr = this;
    //   var _len = _arr.length;
    //   var _arg2 = arguments[1] || window;
    //   var _item;
    //   var newArray = [];

    //   for (var i = 0; i < _len; i++) {
    //     _item = deepClone(_arr[i]);
    //     func.apply(_arg2, [_item, i, _arr]) ? newArray.push(_item) : '';
    //   }
    //   return newArray;
    // }

    // Array.prototype.myFilter = function (cb) {
    //   var res = []
    //   for (var i = 0; i < this.length; i++) {
    //     if (cb(this[i], i, this)) res.push(this[i])
    //   }
    //   return res
    // }

    // myFilter方法
    // var res2 = arr.myFilter(function (item, ind, arr) {
    //   console.log(this); // this指向obj  用箭头函数this指向window
    //   return item.age > 25
    // }, obj)
    // console.log(res2);

    // // filter方法
    // var newArr = arr.filter(function (item, index, array) {
    //   console.log(this);
    //   return item.age > 25;
    // }, obj);
    // console.log(newArr);



    // 3. 重写every方法 
    let arr = [true, true, false, true];

    // var res = arr.every(function (item, key) {
    //   // console.log(item, key)
    //   return item;
    // })

    function myEvery(arr,cb){
      // 思路: 循环数组 一旦遇到false 就返还且停止循环 如果全部都是true 那么返还true结果
      let flag = true //定义一个标志 是true
      for(let i = 0 ;i <arr.length; i++ ){
        flag = flag && cb(arr[i] , i ,arr)
        if(!flag) break // 如果是false 停止循环
      }
      return flag
    }
    // /* 
    // 函数的执行过程
    // 第一次 ： 执行结果  true  && flag = true  ---- > true 赋值给flag = true
    // 第二次： 执行结果  true  && flag = true  ---- > true 赋值给flag = true
    // 第三次： 执行结果 false && flag = true   ----->false 赋值给 flag = false
    // 第四次 ： 执行结果  true  && flag = false  ---- > false 赋值给flag = false
    // */

    var res = myEvery(arr, function(item){
      // console.log(item);// arr里的每个元素 遇到false就退出 
      return item
    })
    console.log(res);


    // 4. 重写some方法  
    // let arr = [true, false, true , true];
    // var res = arr.every(function (item, key) {
    //   // 遇到true会停止函数
    //   console.log(item, key)
    //   return item;
    // })

    // function mySome (arr, cb) {
    //   let flag = false;  // 定义个标志 是false
    //   for (let i = 0; i < arr.length; i++) {
    //     flag = flag || cb(arr[i], i, arr);
    //     // console.log(flag);
    //     if (flag) {
    //       break;
    //     }
    //   }
    //   return flag;
    // }

    // var res = mySome(arr, function (item) {
    //   // console.log(item);
    //   return item;
    // })
    // console.log("结果", res);


  </script>
</body>

</html>